#ifndef _C_GL_PROGRAM_H_
#define _C_GL_PROGRAM_H_

#include "../interface/I_api_Program.h"
#include "../interface/I_api_Blob.h"

#include "../interface/C_gl_VertexShader.h"
#include "../interface/C_gl_PixelShader.h"

class C_gl_ProgramMatrixVariable: public I_api_ProgramMatrixVariable
{
public:
	int m_Location;

	C_gl_ProgramMatrixVariable() { m_Location = 0; }
	~C_gl_ProgramMatrixVariable();

	virtual	bool SetMatrix(float * pData);
	virtual	bool SetMatrixArray(float * pData, int Offset, int Count){ return true; }
	virtual	bool SetMatrixTranspose(float * pData);
	virtual	bool SetMatrixTransposeArray(float * pData, int Offset, int Count){ return true; }
};

class C_gl_ProgramRenderTargetViewVariable: public I_api_ProgramRenderTargetViewVariable
{
public:
	int m_Location;

	C_gl_ProgramRenderTargetViewVariable() { m_Location = 0; }
	~C_gl_ProgramRenderTargetViewVariable();

	virtual	bool SetRenderTarget(I_api_Buffer * pBuffer);
	virtual	bool SetRenderTargetArray(I_api_Buffer ** ppBuffer, int Offset, int Count);
};

class C_gl_ProgramSamplerVariable: public I_api_ProgramSamplerVariable
{
public:
	int m_Location;

	C_gl_ProgramSamplerVariable() { m_Location = 0; }
	~C_gl_ProgramSamplerVariable();

	virtual bool SetSampler(int index, I_api_SamplerState * pSampler);
};

class C_gl_ProgramScalarVariable: public I_api_ProgramScalarVariable
{
public:
	int m_Location;

	C_gl_ProgramScalarVariable() { m_Location = 0; }
	~C_gl_ProgramScalarVariable();

	virtual	bool	SetBool(bool Value);
	virtual	bool	SetBoolArray(bool *pData, int Offset, int Count);
	virtual	bool	SetFloat(float Value);
	virtual	bool	SetFloatArray(float *pData, int Offset, int Count);
	virtual	bool	SetInt(int Value);
	virtual	bool	SetIntArray(int *pData, int Offset, int Count);
};

class C_gl_ProgramVectorVariable: public I_api_ProgramVectorVariable
{
public:
	int m_Location;

	C_gl_ProgramVectorVariable() { m_Location = 0; };
	~C_gl_ProgramVectorVariable();

	virtual	bool	SetBoolVector(bool *pData){ return true; }
	virtual	bool	SetBoolVectorArray(bool *pData, int Offset, int Count){ return true; }
	virtual	bool	SetFloatVector(float *pData);
	virtual	bool	SetFloatVectorArray(float * pData, int Offset, int Count);
	virtual	bool	SetIntVector(int * pData);
	virtual	bool	SetIntVectorArray(int *pData, int Ofset, int Count);
};

class C_gl_ProgramVariable: public I_api_ProgramVariable
{
public:
	int m_Location;

	C_gl_ProgramVariable(){ m_Location = 0; }
	~C_gl_ProgramVariable() {}

	virtual	I_api_ProgramRenderTargetViewVariable	*	AsRenderTargetView();
	virtual	I_api_ProgramMatrixVariable						*	AsMatrix();
	virtual	I_api_ProgramSamplerVariable					*	AsSampler();
	virtual	I_api_ProgramScalarVariable						*	AsScalar();
	virtual	I_api_ProgramVectorVariable						*	AsVector();
};

class C_gl_Program: public I_api_Program
{
	friend class I_api_Device;
	friend class C_gl_Device;

protected:
	int m_Id;

	C_gl_Program(I_api_VertexShader *pVS, I_api_PixelShader *pPS, I_api_Blob **ppErrorMsg);
	//C_gl_Program(I_api_VertexShader *pVS, I_api_PixelShader *pPS, I_api_Blob **ppErrorMsg);

public:
	C_gl_Program(){}
	~C_gl_Program(){}

	virtual	I_api_ProgramVariable	*	GetVariableByIndex(int index);
	virtual	I_api_ProgramVariable	*	GetVariableByName(char * pName);

	virtual	void	*	Get();
};


#endif